;enter PM and direct display by filling the Video card buffer at 0b8000h
;compiled using fasm 1.69

  format mz
  include '../common/pminc.asm'
  
xfer_len=16
;~~~~~~~~~~~~~~~~~~~~~~~~

.data gdts
  .start_xdt_block GDT
    DUMMY_DESC
    normal  DESC  0, 0xffff, SDT_DATA_RW

    sc32 MZDESC code32, code32.limit, SDT_CODE_RE+SDT_DEFAULT32
    sc16 MZDESC code16, 0xffff, SDT_CODE_RE
    sspr MZDESC code32_subps, code32_subps.limit, SDT_CODE_RE+SDT_DEFAULT32
    sstk32 MZDESC stk32, stk32.limit, SDT_DATA_RW+SDT_DEFAULT32
    sgd   MZDESC gdts, gdts.limit, SDT_DATA_RW
    
    ssrc  DESC 12000h, -1, SDT_DATA_RW ; 120000h
    svdo  DESC 0xb800, 3999, SDT_DATA_RW ; 0xb8000    
  .end_xdt_block

lx dw 0
cy dw 0

VgdtR XDTR GDT.limit,0

orgSP dw 0
orgSS dw 0

disp1 db 13,10,"Go on next 16 bytes memory dump display?(Y/N)",'$'
disp2 db 13,10,"Proggy NOW exit, see you next time",13,10,'$'

.code main

init_xdt_proc


start:
  mov eax,gdts
  mov ds,ax
  
  shl eax,4
  shld  edx,eax,16        
  mov word [VgdtR.base_lo],ax
  mov word [VgdtR.base_hi],dx
  
  mov si,GDT
  mov cx,GDT.items
  call ..init_xdt

  mov [orgSP],sp
  mov [orgSS],ss

enter_anew_to_display:
  cli 
  lgdt fword [VgdtR]
  EnableA20
  SetCr0Pebit
  jmp sc32.gsel:pmode_32

at_real_mode:
  mov ax,gdts
  mov ds,ax
  lss sp,dword [orgSP]
  DisableA20
  sti
  ;-----------------
  mov dx,disp1
  iDos21 9
@@:
  iDos21 1
  and al,not 20h
  cmp al,'Y'
  je  n_times
  cmp al,'N'
  jne @B

  mov dx,disp2
  iDos21 9

  mov ax,4c00h
  int 21h

n_times:
  add [ssrc.baseL],16
  adc [ssrc.baseM],0
  adc [ssrc.baseH],0
  add [lx],1                  ;adjust lines and coloumns
  add [cy],0

  jmp enter_anew_to_display

  ;------------------
.code32 code32
pmode_32:
  mov ax,sstk32.gsel
  mov ss,ax
  mov esp,stk32.size
  mov ax,ssrc.gsel
  mov ds,ax
  mov ax,svdo.gsel
  mov es,ax
  
  xor esi,esi
  xor edi,edi
  call sspr.gsel:GetXY
  mov ecx,xfer_len

next_char:
  lodsb
  
  mov ah,4fh          ;white on red
  push ax
  call b2a
  shl eax,16
  pop ax

  shr al,4  
  call b2a
  stosd
  mov al,' '
  stosw
  loop next_char  
  jmp sc16.gsel:pmode_16

b2a:
  b2Asc
  ret

.code code16
pmode_16:  
  xor si,si
  add di,5*2
  mov cx,16
  mov ah,4fh
@@:
  lodsb
  cmp al,7fh
  ja not_printable
  cmp al,20h
  ja print
not_printable:
  mov al,'.'
print:
  stosw
  loop @B

  mov ax,normal.sel
  mov ds,ax
  mov es,ax
  mov ss,ax
  ClrCr0Pebit
  jmp main:at_real_mode

.code32 code32_subps
GetXY:  
  push ds eax
  mov ax,sgd.gsel
  mov ds,ax
  
  movzx eax,[cy]
  shl eax,2
  movzx edi,[lx]
  imul edi,edi,80*2
  add edi,eax
  cmp edi,24*80*2
  jbe @F
  mov edi,0
@@:
  pop eax ds
  retf

.stack stk32
buff  rb 256



.end main:start
